﻿using System;
using System.Collections.Generic;
using System.Linq;
using AutoMapper;
using ERP.BLL.UserApp.Dtos;
using ERP.Common.Extensions;
using ERP.Common.Model;
using ERP.Common.Utils;
using ERP.IDAL;
using ERP.IDAL.IRepositories.basic;
using ERP.Model.Entities;

namespace ERP.BLL.UserApp
{
    public class UserService : IUserService
    {
        private readonly IUserRepository _userRepository;
        private readonly IRoleRepository _roleRepository;
        private readonly IUserRoleRepository _userRoleRepository;
        private readonly IUnitOfWork _unitOfWork;
        public UserService(
            IUserRepository userRepository,
            IRoleRepository roleRepository,
            IUserRoleRepository userRoleRepository,
            IUnitOfWork unitOfWork)
        {
            _userRepository = userRepository;
            _roleRepository = roleRepository;
            _userRoleRepository = userRoleRepository;
            _unitOfWork = unitOfWork;
        }

        public bool CheckIsNameExist(string attr, string attrValue)
        {
            switch (attr)
            {
                case "UserName":
                    {
                        var user = _userRepository.FirstOrDefaultAsync(t => t.UserName == attrValue).Result;
                        return user != null;
                    }
                case "LoginName":
                    {
                        var user = _userRepository.FirstOrDefaultAsync(t => t.LoginName == attrValue).Result;
                        return user != null;
                    }
            }

            return false;
        }

        public int Insert(UserDto dto)
        {
            const string u = "UserName";
            const string l = "LoginName";
            var checkUserName = CheckIsNameExist(u, dto.UserName);
            var checkLoginName = CheckIsNameExist(l, dto.LoginName);

            if (checkLoginName || checkUserName) return checkLoginName ? 1 : 2;
            _userRepository.InsertAsync(Mapper.Map<User>(dto));
            return 0;

        }

        public void Delete(Guid userId)
        {
            try
            {
                _unitOfWork.BeginTransaction();
                _userRoleRepository.Delete(t => t.UserId == userId);
                _userRepository.Delete(userId);
                _unitOfWork.CommitTransaction();
            }
            catch (Exception)
            {
                _unitOfWork.RollbackTransaction();
                throw;
            }
        }

        public void DeleteBatch(List<Guid> ids)
        {
            throw new NotImplementedException();
        }

        public PagedResultModel<UserDto> GetUserPageList(int pageIndex, int pageSize)
        {
            return Mapper.Map<List<UserDto>>(_userRepository.LoadPageList(pageIndex, pageSize, out var rowCount, t => true, t => t.Id, false)).ApplyToPage(pageIndex, pageSize, rowCount);
        }

        public UserDto GetUser(string loginName)
        {
            return Mapper.Map<UserDto>(_userRepository.GetAllIncluding(t => t.UserRoles).FirstOrDefault(t => t.LoginName == loginName));
        }

        public UserDto GetUser(Guid id)
        {
            return Mapper.Map<UserDto>(_userRepository.FirstOrDefaultAsync(t => t.Id == id).Result);
        }

        public bool Update(UserDto dto)
        {
            var user = _userRepository.UpdateAsync(Mapper.Map<User>(dto),
                t =>
                {
                    t.UserName = dto.UserName;
                    t.Email = dto.Email;
                    t.Phone = dto.Phone;
                    t.DepartmentId = dto.DepartmentId;
                });
            return user != null;
        }

        public int ValidateUser(string loginame, string password)
        {
            UserDto dto;
            try
            {
                dto = Mapper.Map<UserDto>(_userRepository.FirstOrDefaultAsync(u => u.LoginName == loginame).Result);
            }
            catch (Exception e)
            {
                Log4NetExtension.ErrorFileSync(">>>>>>>>访问验证登陆名称是否存在后台信息异常", e);
                return UserExceptionCode.USER_ACCESS_EXCEPTION;
            }
            if (dto == null)
            {
                return UserExceptionCode.USER_NOT_EXIST;
            }

            try
            {
                dto = Mapper.Map<UserDto>(_userRepository.FirstOrDefaultAsync(u => u.LoginName == loginame && u.Password == password).Result);
            }
            catch (Exception e)
            {
                Log4NetExtension.ErrorFileSync("访问验证用户密码后台信息异常", e);
                return UserExceptionCode.USER_ACCESS_EXCEPTION;
            }
            return dto == null ? UserExceptionCode.USER_PASSWORD_ERROR : UserExceptionCode.USER_CONDITION_FIT;
        }

        public List<Guid> GetRolesByUser(Guid userId)
        {
            return _userRoleRepository.GetAllListAsync(t => t.UserId == userId).Result.Select(t => t.RoleId).ToList();
        }


        public bool UpdateUserRole(Guid userId, List<UserRoleDto> userRoles)
        {
            var oldUserRoles = _userRoleRepository.GetAllListAsync(t => t.UserId == userId).Result;
            oldUserRoles.ForEach(t => _userRoleRepository.Delete(t));
            userRoles.ForEach(t => _userRoleRepository.InsertAsync(Mapper.Map<UserRole>(t)));
            return true;
        }


    }

}
